package com.november.lottery.base;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.november.lottery.utils.PageUtils;
import com.november.lottery.utils.WebUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

/**
 * @author Jr.November
 */
public abstract class BaseMyController<T extends MyBaseModel> {

    protected abstract MyService<T> getService();

    /**
     * 默认通过分页查询方法
     *
     * @param filter   查询条件 前端传入json格式的map，只接受字符串类型的查询；其他类型需要自己构造方法
     * @param pageable 分页条件
     */
    @GetMapping(value = {"page", ""})
    public ResponseEntity<Object> listByPage(@RequestParam(required = false, defaultValue = "{}") String filter,
                                             Pageable pageable) {
        IPage page = afterListByPage(list(filter, pageable));
        return WebUtils.success(page);
    }

    /**
     * 自定义列表查询结果
     */
    protected IPage afterListByPage(IPage page) {
        return page;
    }

    /**
     * list核心方法
     *
     * @param filter   JSON格式的筛选参数
     * @param pageable 分页信息
     * @return 分页结果
     */
    protected IPage<T> list(String filter, Pageable pageable) {
        // beforePage 可以被继承替换
        QueryWrapper<T> query = beforePage(filter);
        return getService().page(PageUtils.toMybatisQuery(pageable), query);
    }

    /**
     * 可以被替换，实现自定获取filter的方法
     */
    protected QueryWrapper<T> beforePage(String filter) {
        if (Strings.isEmpty(filter)) {
            filter = "{}";
        }
        QueryWrapper<T> query = new QueryWrapper<>();
        return query;
    }

    /**
     * 默认保存修改方法
     */
    @PostMapping(value = {"save","","update"})
    public ResponseEntity<Object> save(@RequestBody T entity) throws BaseException {
        T t = beforeSave(entity);
        T saved = getService().saveOrUpdateAndReturn(t);
        return WebUtils.success(saved);
    }



    /**
     * 保存之前的操作, 可以被替换，实现自定义方法
     */
    protected T beforeSave(T entity) {
        return entity;
    }

    /**
     * 通过id获取实体
     *
     * @param id 主键
     * @return 有数据时返回实体
     */
    @GetMapping("get")
    public ResponseEntity<Object> getById(Integer id) {
        T entity = getService().getById(id);
        return WebUtils.success(afterGetById(entity));
    }

    /**
     * 通过id获取实体
     * @param id 主键
     * @return 有数据时返回实体
     * @throws BaseException 异常处理
     */
    @GetMapping("{id}")
    public ResponseEntity<Object> getBy(@PathVariable(name = "id") Integer id) throws BaseException{
        T entity = getService().getById(id);
        return WebUtils.success(afterGetById(entity));
    }

    /**
     * 获取实体之后
     */
    protected Object afterGetById(T entity) {
        return entity;
    }

    /**
     * 通过id删除实体
     */
    @PostMapping({"delete", "deleteById"})
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<Object> delete(Integer id) throws BaseException {
        if(id == null){
            throw BaseException.throwDataError("id为空");
        }
        this.getService().removeById(this.beforeDelete(id));
        return WebUtils.success("success");
    }

    /**
     * 删除之前的操作
     */
    protected int beforeDelete(Integer id) {
        return id;
    }
}
